<?php

/*
 * Copyright (C) 2009 - 2011 Pham Cong Dinh
 *
 * This file is part of Spica.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

/**
 * The <code>SpicaBBCodeFilter</code> instances are used to transform any text
 * contains bbcode into valid HTML string.
 *
 * namespace spica\core\filter\BBCodeFilter
 *
 * @category   spica
 * @package    core
 * @subpackage filter
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      April 21, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: BaseFilter.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaBBCodeFilter implements SpicaDataFilter
{
    /**
     * The mapping between rule name and its regular expression.
     *
     * @var array
     */
    protected static $_regex = array(
      'b'  => '#\[b\](.+?)\[/b\]#is',
      'i'  => '#\[i\](.+?)\[/i\]#is',
      'u'  => '#\[u\](.+?)\[/u\]#is',
      's'  => '#\[s\](.+?)\[/s\]#is',
      'ul' => '#\[ul\](.+?)\[/ul\]#is',
      'ol' => '#\[ol\](.+?)\[/ol\]#is',
      'li' => '#\[li\](.+?)\[/li\]#is',
      'quote'  => '#\[quote\](.+?)\[/quote\]#is',
      'size'   => '#\[size=(\d)\](.+?)\[/size\]#is',
      'color'  => '#\[color=([a-z0-9\#]+)\](.+?)\[/color\]#is',
      'center' => '#\[center\](.+?)\[/center\]#is',
      'url'    => '#\[url\](.+?)\[\/url\]#ims',
      'url2'   => '#\[url=(.+?)\](.+?)\[/url\]#is',
      'img'    => '#\[img\](.+?)\[/img\]#is',
      'img2'   => '#\[img=([\d\.]+)x([\d\.]+)\](.+?)\[/img\]#is',
    );

    /**
     * The mapping between rule name and its HTML replacement.
     *
     * @var array
     */
    protected static $_replacement = array(
      'b'  => '<strong>\\1</strong>',
      'i'  => '<span style="font-style: italic;">\\1</span>',
      'u'  => '<span style="text-decoration: underline;">\\1</span>',
      's'  => '<span style="text-decoration: line-through;">\\1</span>',
      'ul' => '<ul>\\1</ul>',
      'ol' => '<ol>\\1</ol>',
      'li' => '<li>\\1</li>',
      'quote'  => '<blockquote>\\1</blockquote>',
      'size'   => '<span style="font-size: \\1;">\\2</span>',
      'color'  => '<span style="color: \\1;">\\2</span>',
      'center' => '<div style="text-align: center;">\\1</div>',
      'url'    => '<a href="\\1">\\1</a>',
      'url2'   => '<a href="\\1">\\2</a>',
      'img'    => '<img src="\\1" alt="BBCode image" />',
      'img2'   => '<img width="\\1" height="\\2" src="\\3" alt="BBCode image" />',
    );

    /**
     * The mapping between rule name and its relacement after text is stripped.
     *
     * @var array
     */
    protected static $_stripped = array(
      'b' => '\\1',
      'i' => '\\1',
      'u' => '\\1',
      's' => '\\1',
      'ul' => '\\1',
      'ol' => '\\1',
      'li' => '\\1',
      'quote'  => '\\1',
      'size'   => '\\2',
      'color'  => '\\2',
      'center' => '\\2',
      'url'    => '\\1',
      'url2'   => '\\2',
      'img'    => '\\2',
      'img2'   => '\\3',
    );

    /**
     * Filtering mode. This property takes 2 values:
     *
     * + 1 means transforming BBCode to HTML
     * + 2 means stripping BBCode
     *
     * @var int
     */
    protected $_mode;

    /**
     * Constructs an object of <code>SpicaBBCodeFilter</code>.
     *
     * @param int $mode Filtering mode, default to 1 (transforming BBCode to HTML).
     *                  Another value 2: stripping BBCode
     */
    public function __construct($mode = 1)
    {
        $this->_mode = (int) $mode;
    }

    /**
     * Adds or alters filtering rule in this filter.
     *
     * @param string $name  Filter rule name
     * @param string $regex Rule regular expression
     * @param string $replacement Back reference to HTML replacement
     * @param string $stripped Back reference to content to reserve
     *                         when BBCode is stripped in stripping mode.
     */
    public function setRule($name, $regex, $replacement = null, $stripped = null)
    {
        self::$_regex[$name] = $regex;

        if (null !== $replacement)
        {
            self::$_replacement[$name] = $replacement;
        }

        if (null !== $stripped)
        {
            self::$_stripped[$name] = $stripped;
        }
    }

    /**
     * (non-PHPdoc)
     * @see trunk/library/spica/core/SpicaDataFilter#doFilter()
     */
    public function doFilter($text)
    {
        if (1 === $this->_mode)
        {
            return preg_replace(self::$_regex, self::$_replacement, $text);
        }

        return preg_replace(self::$_regex, self::$_stripped, $text);
    }
}

/**
 * The <code>SpicaReverseBBCodeFilter</code> instances are used to transform HTML
 * container tags back to BB code.
 *
 * namespace spica\core\filter\ReverseBBCodeFilter
 *
 * FIXME
 *
 * @category   spica
 * @package    core
 * @subpackage filter
 * @author     Pham Cong Dinh <pcdinh at phpvietnam dot net>
 * @since      Version 0.3
 * @since      April 24, 2009
 * @copyright  Pham Cong Dinh (http://www.phpvietnam.net)
 * @license    http://www.gnu.org/licenses/lgpl-3.0.txt
 * @version    $Id: BaseFilter.php 1869 2011-01-07 18:55:25Z pcdinh $
 */
class SpicaReverseBBCodeFilter implements SpicaDataFilter
{
    /**
     * (non-PHPdoc)
     * @see trunk/library/spica/core/SpicaDataFilter#doFilter()
     */
    public function doFilter($text)
    {
        // FIXME
    }
}
?>